/*
 * @Description:
 * @Author: dh
 * @Date: 2021-12-17 11:11:32
 * @LastEditors: dh
 * @LastEditTime: 2025-09-11 17:05:17
 */
/* TODO 自定义 Object.create ================================================================================ */
// 简易版
function create(obj) {
	function F() {}
	F.prototype = obj
	return new F()
}

// 完整版 将传入的对象作为原型 
function newCreate(proto, propertiesObject) {
	if (typeof proto !== 'object' && typeof proto !== 'function') {
		throw TypeError('Object prototype may only be an Object: ' + proto)
	}

	function F() {}
	F.prototype = proto
	const o = new F()

	if (propertiesObject) {
		Object.keys(propertiesObject).forEach(prop => {
			let desc = propertiesObject[prop]
			if (typeof desc !== 'object' || desc === null) {
				throw TypeError('Object prorotype may only be an Object: ' + desc)
			} else {
				Object.defineProperty(o, prop, desc)
			}
		})
	}

	return o
}

/* TODO 自定义 Object.freeze ================================================================================ */
// Object.freeze冻结一个对象，让其不能再添加/删除属性，也不能修改该对象已有属性的可枚举性、可配置可写性，也不能修改已有属性的值和它的原型属性，最后返回一个和传入参数相同的对象。
function myFreeze(obj) {
	// 判断参数是否为Object类型，如果是就封闭对象，循环遍历对象。去掉原型属性，将其writable特性设置为false
	if (obj instanceof Object) {
		Object.seal(obj) // 封闭对象 以防止新属性 _被添加_，或者存在属性 _被移除_.然而，你仍然可以对存在属性进行更改。
		for (let key in obj) {
			// 该方法仅在目标属性为对象自身属性时返回true,而当该属性是从原型链中继承而来或根本不存在时，返回false。
			if (obj.hasOwnProperty(key)) {
				Object.defineProperty(obj, key, {
					writable: false, // 设置只读
				})
				// 如果属性值依然为对象，要通过递归来进行进一步的冻结
				myFreeze(obj[key])
			}
		}
	}
}

/* TODO 自定义 Object.assign ================================================================================ */
//  Object.assign(源对象，目标对象，目标对象 如果只有一个参数，此参数为对象，直接返回该参数，非对象会转换为对象返回
function assign(target, ...source) {
	if (target == null) {
		throw new TypeError('Cannot convert undefined or null to object')
	}
	let ret = Object(target)
	source.forEach(function (obj) {
		if (obj != null) {
			for (let key in obj) {
				if (obj.hasOwnProperty(key)) {
					ret[key] = obj[key]
				}
			}
		}
	})
	return ret
}

/* TODO 自定义 Object.entries ================================================================================ */
function entries(obj) {
	let arr = []
	for (let k of Object.keys(obj)) {
		arr.push([k, obj[k]])
	}
	return arr
}
